""" 

    Funfacts.py used in RepresentedBy Facebook application
    http://apps.facebook.com/representedby/
    
    This page is a webservice which randomly picks one fact about your and returns it as a JSON object.
    Think of this as the /network page, but modularized.
         
"""

__author__ = "Will Turnage (will@wubbahed.com)"
__version__ = "0.1.0"
__copyright__ = "Copyright (c) 2009 wubbahed.com"
__license__ = "GPLv3"


import os
import wsgiref.handlers
import facebook
import const
import string
import random

from sets import Set
from django.utils import simplejson
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import urlfetch
from google.appengine.ext import db
from utils import fbUtil, dbUtil, UserDistrict, SunlightUtil

class MainHandler(webapp.RequestHandler):
    
    def get(self):
        self.post()
        
    def post(self):
        
        self.response.headers["Content-Type"] = "application/json; charset=utf-8"
        jsonOutput = {"result":"ok", "message":"", "funfact":""}
        
        try:
            
            
            self.facebookapi = fbUtil().checkFacebookAppInstalled(self, False)
            if self.facebookapi is None:
                jsonOutput["result"] = "error"
                jsonOutput["message"] = "not logged in"
            else:
            

                friend_ids = self.facebookapi.friends.get()
                if friend_ids is None:
                    friend_ids = [self.facebookapi.uid]
                elif len(friend_ids) == 0:
                    friend_ids = [self.facebookapi.uid]
                else:
                    friend_ids.append(self.facebookapi.uid)
                    
                friends_with_app_ids = self.facebookapi.friends.getAppUsers()
                if friends_with_app_ids is None:
                    friends_with_app_ids = [self.facebookapi.uid]
                elif len(friends_with_app_ids) == 0:
                    friends_with_app_ids = [self.facebookapi.uid]
                else:
                    friends_with_app_ids.append(self.facebookapi.uid)
      
                friend_count = len(friends_with_app_ids)
                non_US_friends = 0
                unknown_friends = 0
                
                rep_set = {}
                states = {}
                sen_set = Set([])
                
                popularity = {"state":{"states":[], "count":0}}
                
                results = []
                if friends_with_app_ids is not None:
                    if len(friends_with_app_ids) > 0:
                        for friend in friends_with_app_ids:
                            query = UserDistrict.all()
                            query.filter("uid =", int(friend))
                            results = query.fetch(1)
          
                            for result in results:
                                try:
                                    friend_ids.remove(str(result.uid))
                                except ValueError:
                                    pass

                                if result.rep:
                                    if rep_set.has_key(result.rep):
                                        # rep_set[result.rep].append(appUser)
                                        rep_set[result.rep]["friends"] = rep_set[result.rep]["friends"]+ 1
                                    else:
                                        # rep_set[result.rep] = [[{"id": result.rep, "name": const.FRIENDLY_NAME[result.rep]}], appUser]
                                        rep_set[result.rep] = {"id": result.rep, "name": const.FRIENDLY_NAME[result.rep], "friends": 1}
                                                                        
                                        
                                if result.state:
                                    if states.has_key(result.state):
                                        # states[result.state].append(appUser)
                                        states[result.state]["friends"] = states[result.state]["friends"]+ 1
                                        if (states[result.state]["friends"] == popularity["state"]["count"]):
                                            popularity["state"]["states"].append(str.title(const.STATES[result.state]))
                                        elif (states[result.state]["friends"] > popularity["state"]["count"]):
                                            popularity["state"]["states"] = [str.title(const.STATES[result.state])]  
                                    else:
                                        #states[result.state] = [[], appUser]
                                        states[result.state] = {"state": result.state, "friends": 1, "senators":[]}
                                        for senator in const.LEGISLATORS_BY_STATE[result.state]["senators"]:
                                            sen_set.add(senator)
                                        #    states[result.state][0].append({"id": senator, "name": const.FRIENDLY_NAME[senator]})
                                            states[result.state]["senators"].append({"id": senator, "name": const.FRIENDLY_NAME[senator]})
                                            
                                                
                                                  
                friends_loc = self.facebookapi.users.getInfo(friend_ids, ['uid', 'current_location'])  
                #for all your other friends, try and look up their information
                for friend in friends_loc :
                    if friend:
                        sunlight = SunlightUtil(const.SUNLIGHT_API_KEY)
                        friendInfo = sunlight.getDistrictForUser(friend["uid"], friend["current_location"])
                
                        if friendInfo is not None:
                            if (friendInfo.has_key("state")):
                                
                                friend_count = friend_count + 1
                                if states.has_key(friendInfo["state"]):
                                    states[friendInfo["state"]]["friends"] = states[friendInfo["state"]]["friends"]+ 1
                                    if (states[friendInfo["state"]]["friends"] == popularity["state"]["count"]):
                                        popularity["state"]["states"].append(str.title(const.STATES[friendInfo["state"]]))
                                    elif (states[friendInfo["state"]]["friends"] > popularity["state"]["count"]):
                                        popularity["state"]["states"] = [str.title(const.STATES[friendInfo["state"]])] 
                                else:                
                                    #states[friendInfo["state"]] = [[], friend["uid"]]
                                    states[friendInfo["state"]] = {"state": friendInfo["state"], "friends": 1, "senators":[]}
                                    for senator in const.LEGISLATORS_BY_STATE[friendInfo["state"]]["senators"]:
                                        sen_set.add(senator)
                                        #states[friendInfo["state"]][0].append({"id": senator, "name": const.FRIENDLY_NAME[senator]})
                                        states[friendInfo["state"]]["senators"].append({"id": senator, "name": const.FRIENDLY_NAME[senator]})
    
                                row = sunlight.getLegislatorsFromLocationRow(friendInfo)
                                if row.has_key("rep"):
                                    if rep_set.has_key(row["rep"]):
                                        rep_set[row["rep"]]["friends"] = rep_set[row["rep"]]["friends"] + 1
                                    else:
                                        rep_set[row["rep"]] = {"id": row["rep"], "name": const.FRIENDLY_NAME[row["rep"]], "friends": 1}

                        else:
                            if friend["current_location"] is not None:
                                if friend["current_location"].has_key("country") :
                                    if friend["current_location"]["country"] != "United States" :
                                        non_US_friends = non_US_friends + 1
                                    else:
                                        unknown_friends = unknown_friends + 1
                                else:
                                    unknown_friends = unknown_friends + 1
                            else:
                                unknown_friends = unknown_friends + 1
                    else:
                        unknown_friends = unknown_friends + 1
                            
                                                                                 
                pick = random.randint(0, 5)
                if pick == 0:
                    jsonOutput["funfact"] = "My network is represented by " + str(len(sen_set))+ " out of 100 Senators" 
                elif pick == 1:
                    jsonOutput["funfact"] = "My network is represented by " + str(len(rep_set))+ " out of 435 Representatives" 
                elif pick == 2:
                    jsonOutput["funfact"] = "The most popular state in my network is " + popularity["state"]["states"][0]
                elif pick == 3:
                    jsonOutput["funfact"] = "I have friends in " + str(len(states.keys())) + " states"
                else:
                    committee_set = Set(const.COMMITTEES.keys())
                    committee_member_set = Set([])
                    committee_chair_set = Set([])
                    for member in rep_set.keys():
                        if const.COMMITTEE_BY_MEMBER.has_key(member):
                            for comm in const.COMMITTEE_BY_MEMBER[member]:
                                committee_member_set.add(comm)
                        if const.COMMITTEE_BY_CHAIR.has_key(member):
                            for comm in const.COMMITTEE_BY_CHAIR[member]:
                                committee_chair_set.add(comm)
                    for member in sen_set:
                        if const.COMMITTEE_BY_MEMBER.has_key(member):
                            for comm in const.COMMITTEE_BY_MEMBER[member]:
                                committee_member_set.add(comm)
                        if const.COMMITTEE_BY_CHAIR.has_key(member):
                            for comm in const.COMMITTEE_BY_CHAIR[member]:
                                committee_chair_set.add(comm)
                    if pick == 4:
                        jsonOutput["funfact"] = "My network has direct influence over " + str(len(committee_chair_set)) + " out of " + str(len(const.COMMITTEES)) + " Congressional Committee Chairs"
                    else:
                        jsonOutput["funfact"] = "My network has direct influence over " + str(len(committee_member_set)) + " out of " + str(len(const.COMMITTEES)) + " Congressional Committees"
           
            
        except urlfetch.DownloadError, e:
            jsonOutput["result"] = "error"
            jsonOutput["message"] = str(e.msg)
            
        except facebook.FacebookError, e:
            jsonOutput["result"] = "error"
            jsonOutput["message"] = str(e.msg)
                       
        self.response.out.write(simplejson.dumps(jsonOutput))    
  
def main():
	application = webapp.WSGIApplication([('/fb/funfacts', MainHandler)],
									   debug=True)
	run_wsgi_app(application)

# load our custom filters		   
webapp.template.register_template_library('customfilters')

if __name__ == '__main__':
	main()
